package biz

import (
	"fmt"
	"log"
	"strings"

	"github.com/unidoc/unioffice/document"
	"org.knight/api"
	"org.knight/biz/handler"
	"org.knight/biz/repo"
	"org.knight/data"
)

type PipelineEntry struct {
	PipDiscriminator api.PipelineDiscriminator
	pips             map[string]api.Pipeline
	tableHandler     api.TableHandler
}

func (entry *PipelineEntry) OnEvent(e api.Event) {
	pip_id := entry.PipDiscriminator.ChoosePipeline(e)
	pip := entry.pips[pip_id]
	if pip == nil {
		panic(fmt.Sprintf("no pip named %s", pip_id))
	}
	pip.OnEvent(e)
}

type DocParser struct {
	entryPoint PipelineEntry
}

func (d *DocParser) Init() {

	pips := make(map[string]api.Pipeline, 2)

	ieChan := make(chan data.InfoElement, 3)

	dbRepo := &repo.DBRepository{}
	ieConsumer := IEConsumer{repo: dbRepo}

	go func(ies chan data.InfoElement) {
		//
		for {
			ie := <-ies
			log.Printf("processing IE:=%s  ---  \n", ie)
			ieConsumer.Persist(&ie)
		}
		//log.Printf("captured IE=%v \n", ie.Name)
	}(ieChan)

	iePipe := SimplePipeline{ReadyQueue: ieChan,
		SpecHandlers: [] api.SpecHandler{
			&handler.SpecificationHandler{Repo: dbRepo},
		},
		Handlers: []api.Handler{
		&handler.IEIdCaptureHandler{},
		&handler.ContentCaptureHandler{},
	},
		CtxCache: make(map[string]*api.Context)}
	pips["ie"] = iePipe

	pipDiscriminator := SimplePipelineDiscriminator{}

	//entryPoint := PipelineEntry{PipDiscriminator: pipDiscriminator, pips: pips, tableHandler: SimpleTableHandler{}}
	d.entryPoint = PipelineEntry{PipDiscriminator: pipDiscriminator, pips: pips}
}

func (d *DocParser) Parse(filename string) {

	doc, err := document.Open(filename)

	defer doc.Close()

	if err != nil {
		panic(fmt.Sprintf("Error open file: %s", filename))
	}

	//for _, table := range doc.Tables() {
	//	d.entryPoint.tableHandler.Handle(table)
	//}

	spec_name, spec_version := normalizeFileName(filename)

	for _, p := range doc.Paragraphs() {
		d.entryPoint.OnEvent(api.Event{P: p, SpecName: spec_name, SpecVersion: spec_version})
	}
}

func normalizeFileName(filename string) (string, string) {

	i := strings.LastIndex(filename, "/")
	j := strings.LastIndex(filename, ".docx")
	k := strings.LastIndex(filename, "-")
	if i < 0 || j < 1 || k < i || k > j {
		panic(fmt.Sprintf("bad file name: %s ", filename))
	}

	spec_name := filename[i+1 : k-1]
	spec_version := filename[k+1 : j-1]

	return spec_name, spec_version

}
